package com.dabaozhan.modules.wx_app.facade.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dabaozhan.modules.wx_app.entity.BookBillEntity;
import com.dabaozhan.modules.wx_app.entity.BookBillQueryEntity;
import com.dabaozhan.modules.wx_app.entity.FormQueryEntity;
import com.dabaozhan.modules.wx_app.entity.OperateFormEntity;
import com.dabaozhan.modules.wx_app.entity.OperateQueryEntity;
import com.dabaozhan.modules.wx_app.entity.PurchaseFormEntity;
import com.dabaozhan.modules.wx_app.entity.SaleFormEntity;
import com.dabaozhan.modules.wx_app.facade.OperateFormFacade;
import com.dabaozhan.modules.wx_app.service.BookBillService;
import com.dabaozhan.modules.wx_app.service.PurchaseFormService;
import com.dabaozhan.modules.wx_app.service.SaleFormService;

@Service("operateFormFacade")
public class OperateFormFacadeImpl implements OperateFormFacade{
	
	@Autowired
	private SaleFormService saleFormService;
	@Autowired
	private PurchaseFormService purchaseFormService;
	@Autowired
	private BookBillService bookBillService;
	
	@Override
	public OperateFormEntity getOperate(OperateQueryEntity entity) {
		entity.setBeginTime(getFirstDayOfMonth(entity.getYear(),entity.getMonth()));
		entity.setEndTime(getLastDayOfMonth(entity.getYear(),entity.getMonth()));
		
		FormQueryEntity formQueryEntity = new FormQueryEntity();
		formQueryEntity.setUserId(entity.getUserId());
		formQueryEntity.setBeginTime(entity.getBeginTime());
		formQueryEntity.setEndTime(entity.getEndTime());
		List<SaleFormEntity> saleList = saleFormService.getSaleList(formQueryEntity);
		List<PurchaseFormEntity> purchaseList = purchaseFormService.getPurchaseList(formQueryEntity);
		BookBillQueryEntity bookBillQueryEntity = new BookBillQueryEntity();
		bookBillQueryEntity.setUserId(entity.getUserId());
		bookBillQueryEntity.setBeginTime(entity.getBeginTime());
		bookBillQueryEntity.setEndTime(entity.getEndTime());
		List<BookBillEntity> bookBillList = bookBillService.getBookBillListByTime(bookBillQueryEntity);
		List<BookBillEntity> saleIncomeList = bookBillList.stream().filter(b->b.getBookSubject()==1).collect(Collectors.toList());
		List<BookBillEntity> groceriesIncomeList = bookBillList.stream().filter(b->b.getBookSubject()==2).collect(Collectors.toList());
		List<BookBillEntity> rentIncomeList = bookBillList.stream().filter(b->b.getBookSubject()==3).collect(Collectors.toList());
		List<BookBillEntity> otherIncomeList = bookBillList.stream().filter(b->b.getBookSubject()==4).collect(Collectors.toList());
		List<BookBillEntity> purchaseOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==5).collect(Collectors.toList());
		List<BookBillEntity> payOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==6).collect(Collectors.toList());
		List<BookBillEntity> trafficOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==7).collect(Collectors.toList());
		List<BookBillEntity> rentOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==8).collect(Collectors.toList());
		List<BookBillEntity> repairOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==9).collect(Collectors.toList());
		List<BookBillEntity> otherOutcomeList = bookBillList.stream().filter(b->b.getBookSubject()==10).collect(Collectors.toList());
		BigDecimal saleIncome =  CollectionUtils.isEmpty(saleIncomeList)?BigDecimal.ZERO:saleIncomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal groceriesIncome =  CollectionUtils.isEmpty(groceriesIncomeList)?BigDecimal.ZERO:groceriesIncomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal rentIncome =  CollectionUtils.isEmpty(rentIncomeList)?BigDecimal.ZERO:rentIncomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal otherIncome =  CollectionUtils.isEmpty(otherIncomeList)?BigDecimal.ZERO:otherIncomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal purchaseOutcome =  CollectionUtils.isEmpty(purchaseOutcomeList)?BigDecimal.ZERO:purchaseOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal payOutcome =  CollectionUtils.isEmpty(payOutcomeList)?BigDecimal.ZERO:payOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal trafficOutcome =  CollectionUtils.isEmpty(trafficOutcomeList)?BigDecimal.ZERO:trafficOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal rentOutcome =  CollectionUtils.isEmpty(rentOutcomeList)?BigDecimal.ZERO:rentOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal repairOutcome =  CollectionUtils.isEmpty(repairOutcomeList)?BigDecimal.ZERO:repairOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal otherOutcome =  CollectionUtils.isEmpty(otherOutcomeList)?BigDecimal.ZERO:otherOutcomeList.stream().map(BookBillEntity::getBookPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		
		BigDecimal sysPurchaseOutcome  = CollectionUtils.isEmpty(purchaseList)?BigDecimal.ZERO:purchaseList.stream().map(PurchaseFormEntity::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal sysSaleIncome  = CollectionUtils.isEmpty(saleList)?BigDecimal.ZERO:saleList.stream().map(SaleFormEntity::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
		
		saleIncome = saleIncome.add(sysSaleIncome);
		purchaseOutcome = purchaseOutcome.add(sysPurchaseOutcome);
		
		OperateFormEntity result = new OperateFormEntity();
		result.setSaleIncome(saleIncome.toString());
		result.setGroceriesIncome(groceriesIncome.toString());
		result.setRentIncome(rentIncome.toString());
		result.setOtherIncome(otherIncome.toString());
		result.setPurchaseOutcome(purchaseOutcome.toString());
		result.setPayOutcome(payOutcome.toString());
		result.setTrafficOutcome(trafficOutcome.toString());
		result.setRentOutcome(rentOutcome.toString());
		result.setRepairOutcome(repairOutcome.toString());
		result.setOtherOutcome(otherOutcome.toString());
		BigDecimal totalIncome = saleIncome.add(groceriesIncome).add(rentIncome).add(otherIncome);
		BigDecimal totalOutcome = purchaseOutcome.add(payOutcome).add(trafficOutcome).add(rentOutcome).add(repairOutcome).add(otherOutcome);
		BigDecimal totalProfit = totalIncome.subtract(totalOutcome);
		result.setTotalIncome(totalIncome.toString());
		result.setTotalOutcome(totalOutcome.toString());
		result.setTotalProfit(totalProfit.toString());
		return result;
	}
	
	/**
     * 获取指定年月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {     
        Calendar cal = Calendar.getInstance();   
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份 
        cal.set(Calendar.MONTH, month-1); 
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数 
        cal.set(Calendar.DAY_OF_MONTH,firstDay);  
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(cal.getTime());  
    }
    
    /**
     * 获取指定年月的最后一天 23：59
     * 或者说指定年月下一个月的第一天的0点         这两种等价
     * @param year
     * @param month
     * @return
     */
     public static String getLastDayOfMonth(int year, int month) {     
    	 Calendar cal = Calendar.getInstance();   
         //设置年份
         cal.set(Calendar.YEAR, year);
         //设置月份 
         cal.set(Calendar.MONTH, month); 
         //获取某月最小天数
         int firstDay = cal.getMinimum(Calendar.DATE);
         //设置日历中月份的最小天数 
         cal.set(Calendar.DAY_OF_MONTH,firstDay);  
         cal.set(Calendar.HOUR_OF_DAY, 0);
         cal.set(Calendar.MINUTE, 0);
         cal.set(Calendar.SECOND, 0);
         //格式化日期
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         return sdf.format(cal.getTime());  
     }
}
